package com.zxy.supplier_system.server.controller

import com.zxy.supplier_system.server.controller.GoodsController.GoodsDetail.SubGoodsResponse
import com.zxy.supplier_system.server.entity.Authority
import com.zxy.supplier_system.server.entity.MarketOrder
import com.zxy.supplier_system.server.repository.QueryGoodsUnitResponse
import com.zxy.supplier_system.server.service.MarketOrderService
import com.zxy.supplier_system.server.service.MarketOrderWithProcurementConvertService
import com.zxy.supplier_system.server.utils.GoodsExcelField
import com.zxy.supplier_system.server.utils.IntIdAndName
import com.zxy.supplier_system.server.utils.LongIdAndName
import org.springframework.beans.factory.annotation.Value
import org.springframework.core.io.InputStreamResource
import org.springframework.core.io.Resource
import org.springframework.data.domain.Page
import org.springframework.data.domain.Pageable
import org.springframework.data.domain.Sort
import org.springframework.data.web.SortDefault
import org.springframework.web.bind.annotation.*
import java.math.BigDecimal
import java.time.LocalDate
import java.time.OffsetDateTime
import java.time.Period

@RestController
@RequestMapping("markets/orders")
class MarketOrderController(
    private val marketOrderService: MarketOrderService,
    @Value("classpath:excel/templates/导入卖场订单货品模板.xlsx")
    private val importMarketOrderItemsTemplate: Resource,
    private val marketOrderWithProcurementConvertService: MarketOrderWithProcurementConvertService,
) {

    class QueryMarketOrderRequest(
        val marketIds: List<Int> = emptyList(),
        val startDate: LocalDate?,
        val endDate: LocalDate?,
        val employeeIds: List<Int> = emptyList(),
        val status: MarketOrder.Status?,
        val number: String?,
    )

    @HasAuthority(Authority.卖场_订单_查询)
    @GetMapping
    fun queryMarketOrder(
        queryMarketOrderRequest: QueryMarketOrderRequest,
        @SortDefault(sort = ["createdDateTime"], direction = Sort.Direction.DESC) pageable: Pageable,
    ): Page<QueryMarketOrderResponse> {
        return this.marketOrderService.queryMarketOrder(queryMarketOrderRequest, pageable)
    }

    data class QueryMarketOrderResponse(
        val id: Int,
        val createdBy: IntIdAndName,
        val createdDateTime: OffsetDateTime,
        val lastModifiedDateTime: OffsetDateTime?,
        val goodsKindAmount: Int,
        val market: IntIdAndName,
        val status: MarketOrder.Status,
        val number: String,
    )

    data class UpdateOrderGoodsRequest(
        val goodsList: List<OrderGoodsItem>
    )

    data class OrderGoodsItem(
        val id: Int,
        val amount: Int
    )

    @HasAuthority(Authority.卖场_订单_下单)
    @PatchMapping("{id}/goods")
    fun updateOrderGoods(
        @RequestBody updateOrderGoodsRequest: UpdateOrderGoodsRequest, @PathVariable id: Int,
    ) {
        return this.marketOrderService.updateOrderGoods(id, updateOrderGoodsRequest)
    }

    @HasAuthority(Authority.卖场_订单_查询)
    @GetMapping("{id}")
    fun getMarketOrderDetail(@PathVariable id: Int, includeItems: Boolean = false): MarketOrderDetail {
        return this.marketOrderService.getMarketOrderDetail(id, includeItems)
    }

    data class MarketOrderDetail(
        val id: Int,
        val createdDateTime: OffsetDateTime,
        val createdBy: IntIdAndName,
        val market: IntIdAndName,
        val items: List<MarketOrderItemResponse>,
        val submitDateTime: OffsetDateTime?,
        val deliveryDateTime: OffsetDateTime?,
        val number: String,
    )

    data class MarketOrderItemResponse(
        val id: Int,
        val name: String,
        val barcode: String,
        val price: BigDecimal,
        val amount: Int,
        val createdDateTime: OffsetDateTime,
        val lastModifiedDateTime: OffsetDateTime?,
        val brand: IntIdAndName?,
        val category: IntIdAndName?,
        val factory: IntIdAndName?,
        val amountInOrder: Int,
        val boxSpecification: String?,
        val unit: LongIdAndName?,
        val units: List<QueryGoodsUnitResponse>,
        val registrationCertificateNumber: String?,
        val recordFilingNumber: String?,
        val expressionPeriod: Period?,
        val subGoods: SubGoodsResponse? = null,
        val note: String? = null,
    )

    @HasAuthority(Authority.卖场_订单_查询)
    @GetMapping("employees", params = ["projection=summary"])
    fun getMarketOrderCreatedEmployees(): List<IntIdAndName> {
        return this.marketOrderService.getAllEmployees()
    }


    @HasAuthority(Authority.卖场_订单_下单)
    @PatchMapping("{id}/submit")
    fun submitOrder(@PathVariable id: Int) {
        return this.marketOrderService.submitMarketOrder(id)
    }

    @HasAuthority(Authority.卖场_订单_转化为送货单)
    @PostMapping("{id}/delivery")
    fun delivery(@PathVariable id: Int): Int {
        return this.marketOrderService.delivery(id).id
    }

    @HasAuthority(Authority.卖场_订单_删除)
    @DeleteMapping("{id}")
    fun deleteOrder(@PathVariable id: Int) {
        return this.marketOrderService.delete(id)
    }

    class ExportToExcelRequest(
        val fields: Array<GoodsExcelField> = arrayOf(
            GoodsExcelField.条码,
            GoodsExcelField.名称,
            GoodsExcelField.数量,
            GoodsExcelField.单位,
            GoodsExcelField.零售价,
            GoodsExcelField.总售价,
            GoodsExcelField.库存,
            GoodsExcelField.品牌,
            GoodsExcelField.类别,
            GoodsExcelField.厂商,
            GoodsExcelField.箱规,

            ),
    )

    @GetMapping("{id}/excel")
    fun exportToExcel(@PathVariable id: Int, request: ExportToExcelRequest): InputStreamResource {
        return this.marketOrderService.exportToExcel(id, request)
    }

    @GetMapping("latestUncommited")
    fun queryLatestUncommitedMarketOrder(): List<LatestUncommitedMarketOrder> {
        return this.marketOrderService.queryLatestUncommitedMarketOrder()
    }

    data class LatestUncommitedMarketOrder(
        val id: Int,
        val number: String,
        val goodsAmount: Int,
        val createdDateTime: OffsetDateTime,
        val createdBy: IntIdAndName,
        val market: IntIdAndName,
    )

    @HasAuthority(Authority.卖场_订单_添加货品)
    @GetMapping("items/excel/import/template")
    fun downloadImportTemplate(): InputStreamResource {
        return InputStreamResource(importMarketOrderItemsTemplate.inputStream)
    }

    @PostMapping("{marketOrderId}/convertToProcurement")
    fun convertToProcurement(@PathVariable marketOrderId: Int, procurementSupplierId: Int): Int {
        return marketOrderWithProcurementConvertService.convertToProcurement(marketOrderId, procurementSupplierId).id
    }

}
